﻿using System;
using System.Collections.Generic;
using System.Reflection;
using NHibernate;
using NHibernate.Cfg;

namespace MoroMoro.Samples.ToDoList.Persistence.NHibernate
{
    /// <summary>
    /// NHibernate の設定情報を管理します。
    /// </summary>
    internal sealed class NHConfig
    {
        /// <summary>
        /// 接続文字列と紐付けられた NHibernate Configuration の一覧。
        /// </summary>
        private static Dictionary<string, Configuration> _configurations = new Dictionary<string,Configuration>();

        /// <summary>
        /// 接続文字列と紐付けられた NHibernate セッションファクトリの一覧。
        /// </summary>
        private static Dictionary<string, ISessionFactory> _sessionFactories = new Dictionary<string,ISessionFactory>();


        /// <summary>
        /// 指定した接続文字列に対応する NHibernate Configuration を取得します。
        /// </summary>
        /// <param name="connectionString">接続文字列。</param>
        /// <returns>NHibernate Configuration。</returns>
        public static Configuration GetConfiguration(string connectionString)
        {
            if (!_configurations.ContainsKey(connectionString))
            {
                var configuration = new Configuration();
                configuration.SetProperty("proxyfactory.factory_class", "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");
                configuration.SetProperty("dialect", "NHibernate.Dialect.MsSqlCe40Dialect");
                configuration.SetProperty("connection.provider", "NHibernate.Connection.DriverConnectionProvider");
                configuration.SetProperty("connection.connection_string", connectionString);
                configuration.SetProperty("connection.release_mode", "auto");
                configuration.AddAssembly(Assembly.GetExecutingAssembly());
                _configurations.Add(connectionString, configuration);
            }
            return _configurations[connectionString];
        }

        /// <summary>
        /// 指定した接続文字列に対応する NHibernate セッションファクトリを取得します。
        /// </summary>
        /// <param name="connectionString">接続文字列。</param>
        /// <returns>NHibernate セッションファクトリ。</returns>
        public static ISessionFactory GetSessionFactory(string connectionString)
        {
            if (!_sessionFactories.ContainsKey(connectionString))
            {
                var configuration = GetConfiguration(connectionString); 
                var sessionFactory = configuration.BuildSessionFactory();
                _sessionFactories.Add(connectionString, sessionFactory);
            }
            return _sessionFactories[connectionString];
        }
    }
}
